using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Validation;

namespace CustomerSample
{
	public class Customer : INotifyPropertyChanged, ISupportInitialize
	{
		public event PropertyChangedEventHandler PropertyChanged;

		void RaiseNotify(string propertyName)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}

		private string firstName;

		[StringLengthValidator(1, RangeBoundaryType.Inclusive, 0, RangeBoundaryType.Ignore)]
		[NotNullValidator]
		public string FirstName
		{
			get { return firstName; }
			set { firstName = value; RaiseNotify("FirstName"); }
		}

		private string lastName;

		[StringLengthValidator(1, RangeBoundaryType.Inclusive, 0, RangeBoundaryType.Ignore)]
		[NotNullValidator]
		public string LastName
		{
			get { return lastName; }
			set { lastName = value; RaiseNotify("LastName"); }
		}

		private string nickname;

		// No validation here but we can still use ValidationBinding without problems.
		// It will behave just like a plain Binding.
		public string Nickname
		{
			get { return nickname; }
			set { nickname = value; RaiseNotify("NickName"); }
		}

		private DateTime birthDate;

		[LessThanHundredAndFiftyYearsValidator]
		public DateTime BirthDate
		{
			get { return birthDate; }
			set { birthDate = value; RaiseNotify("BirthDate"); }
		}

		private Address address = new Address();

		[ObjectValidator]
		public Address Address
		{
			get { return address; }
			set { address = value; RaiseNotify("Address"); }
		}

		#region ISupportInitialize Members

		public void BeginInit()
		{
		}

		public void EndInit()
		{
			Validation.ValidateThrow(this);
		}

		#endregion

		public ValidationResults Validate()
		{
			return Validation.Validate(this);
		}
	}

	public class Address : INotifyPropertyChanged, ISupportInitialize
	{
		public event PropertyChangedEventHandler PropertyChanged;

		void RaiseNotify(string propertyName)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}

		private string streetName;

		public string StreetName
		{
			get { return streetName; }
			set { streetName = value; RaiseNotify("StreetName"); }
		}

		private int number;

		[RangeValidator(1, RangeBoundaryType.Inclusive, 5000, RangeBoundaryType.Inclusive)]
		public int Number
		{
			get { return number; }
			set { number = value; RaiseNotify("Number"); }
		}

		private string state;

		// Uf... quite some typing! ;)
		// validates that it's one of the US states.
		[DomainValidator("AL","AK","AS","AZ","AR","CA","CO","CT","DE","DC","FM","FL","GA","GU","HI","ID","IL","IN","IA","KS","KY","LA","ME","MH","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","MP","OH","OK","OR","PW","PA","PR","RI","SC","SD","TN","TX","UT","VT","VI","VA","WA","WV","WI","WY", 
			MessageTemplate="Value is not a valid US state two-letter abbreviation.")]
		public string USState
		{
			get { return state; }
			set { state = value; RaiseNotify("USState"); }
		}

		#region ISupportInitialize Members

		public void BeginInit()
		{
		}

		public void EndInit()
		{
			Validation.ValidateThrow(this);
		}

		#endregion
	}
}
